/* Copyright (c) 2004 Andreas Ernst

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so, subject
to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

package org.flexdock.docking.floating.frames;

import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JDialog;
import javax.swing.JRootPane;

import org.flexdock.docking.Dockable;
import org.flexdock.docking.DockingConstants;
import org.flexdock.docking.DockingManager;
import org.flexdock.docking.DockingPort;
import org.flexdock.docking.state.FloatingGroup;
import org.flexdock.util.RootWindow;

/**
 * @author Andreas Ernst
 * @author Christopher Butler
 */
public class DockingFrame extends JDialog implements DockingConstants {
	private static final BoundsMonitor BOUNDS_MONITOR = new BoundsMonitor();
	private FloatingDockingPort dockingPort;
	private String groupName;
	
	public static DockingFrame create(Component c, String groupName) {
		RootWindow rootWin = RootWindow.getRootContainer(c);
		Component window = rootWin.getRootContainer();
		if(window instanceof DockingFrame) {
			window = ((DockingFrame)window).getOwner();
		}
		
		if(window instanceof Frame)
			return new DockingFrame((Frame)window, groupName);
		if(window instanceof Dialog)
			return new DockingFrame((Dialog)window, groupName);		
		
		return null;
	}
	
    // constructor
    public DockingFrame(Frame owner, String groupName) {
        super(owner);
        initialize(groupName);
    }

    public DockingFrame(Dialog owner, String groupName) {
        super(owner);
        initialize(groupName);
    }

    // private

    private void initialize(String groupName) {
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.NONE);

        //TODO I am not sure null should be passed here,
        // maybe we should use our IDPersistentIdProvider
        dockingPort = new FloatingDockingPort(this, null);
		setContentPane(dockingPort);
		this.groupName = groupName;
		addComponentListener(BOUNDS_MONITOR);
    }

    // override

    protected JRootPane createRootPane() {
        return new RootPane(this);
    }
    
    public DockingPort getDockingPort() {
    	return dockingPort;
    }
    
    public void addDockable(Dockable dockable) {
    	if(dockable==null)
    		return;
    	
    	dockingPort.dock(dockable, CENTER_REGION);
    }
	
	public void destroy() {
		setVisible(false);
		dockingPort = null;
		FloatingGroup group = getGroup();
		if(group!=null)
			group.setFrame(null);
		dispose();
	}
	
	public String getGroupName() {
		return groupName;
	}
	
	public FloatingGroup getGroup() {
		return DockingManager.getFloatManager().getGroup(getGroupName());
	}
	
	private static class BoundsMonitor implements ComponentListener {
		
		public void componentHidden(ComponentEvent e) {
			// noop
		}
		public void componentMoved(ComponentEvent e) {
			updateBounds(e);
		}
		public void componentResized(ComponentEvent e) {
			updateBounds(e);
		}
		
		public void componentShown(ComponentEvent e) {
			updateBounds(e);
		}
		
		private void updateBounds(ComponentEvent evt) {
			Component c = (Component)evt.getComponent();
			if(!(c instanceof DockingFrame))
				return;
			
			DockingFrame frame = (DockingFrame)c;
			FloatingGroup group = frame.getGroup();
			if(group!=null)
				group.setBounds(frame.getBounds());
		}
	}
}